package algorithm3_v3;

import java.io.ByteArrayInputStream;
import java.io.ObjectInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.concurrent.Callable;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Task2 implements Callable<Object> {

	static Logger logger = LoggerFactory.getLogger(Task2.class);
	private final ScheduledFuture<String> timer;
	private final ScheduledExecutorService timer_threat;

	public Task2(ScheduledFuture<String> timer,
			ScheduledExecutorService timer_threat) {
		this.timer = timer;
		this.timer_threat = timer_threat;
	}

	@Override
	public Object call() throws Exception {
		DatagramSocket socket = new DatagramSocket(12345);
		byte[] buf = new byte[1024];
		DatagramPacket packet = new DatagramPacket(buf, buf.length);
		SystemInfo info = SystemInfo.INSTANCE;

		while (true) {
			try {
				socket.receive(packet);
				ByteArrayInputStream bais = new ByteArrayInputStream(buf);
				ObjectInputStream ois = new ObjectInputStream(bais);
				// logger.info("Mezuaren zain");
				Message message = (Message) ois.readObject();
				logger.info("Mezua jasota: " + message.process.toString());
				if (info.p_ts[0] < info.min_ts[0]
						|| (info.p_ts[0] == info.min_ts[0] && info.leader
								.equals("")) // && p<q ??????????
						|| (info.p_ts[0] == info.min_ts[0] && !info.leader
								.equals("")) // && p<=info.leader ??????????
				) {
					info.leader.replace(0, info.leader.length(),
							message.process.toString());
					logger.info("leader berria recovered obea: "
							+ info.leader.toString());
					info.min_ts[0] = message.ts;
					// logger.info("3. Ataza Gelditu");
					if (this.timer != null) {
						this.timer.cancel(false);
					}
					// logger.info("3. Ataza Martxan");
					try {
						this.timer_threat.schedule(new Task3(),
								info.timeout[0], TimeUnit.MILLISECONDS);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}

			} catch (Exception e) {
				logger.info("ERROREA: Task2 mezua jasotzean");
				e.printStackTrace();
			} finally {
				try {
					socket.close();
				} catch (Exception e) {
					logger.info("ERROREA: Task2 socketa ixtean");
					e.printStackTrace();
				}
			}
		}
	}
}
